﻿#ifndef THREAD_SAFE_H
#define THREAD_SAFE_H

#include <unordered_set>
#include <thread>
#include <ReflectX_global.h>

#include "signalslot.h"

class EventLoop;

namespace ThreadSafe
{
    typedef std::thread::id ThreadId;
	class DeleteEvent;


	class REFLECTX_EXPORT Event
	{
	public:
		enum EventType
		{
			None = 0,
			Delete,
			InvokeFunction,
			Timer,
			Other,
		};


		Event(int type);
		virtual ~Event();
		int GetType() { return type; }

	private:
		int type;
	};

	class REFLECTX_EXPORT DeleteEvent :public Event {
	public:
		DeleteEvent();
	};

	class REFLECTX_EXPORT InvokeFunctionEvent :public Event {
	public:
		InvokeFunctionEvent(const std::function<void()>& fun);

		void Invoke();

	private:
		std::function<void()> fun;
	};

	class REFLECTX_EXPORT TimerEvent :public Event {
	public:
		TimerEvent();
	};

	class REFLECTX_EXPORT ThreadSafeBase
    {
	public:
		ThreadSafeBase();
		virtual ~ThreadSafeBase();

		//决定事件处理器所在的线程
		ThreadId thread();
		void MoveToThread(ThreadId id);
		
		//异步析构
		void DeleteLater();

		ConnectionRegistry* GetRegistry();

		void InstallEventFilter(ThreadSafeBase* filter);
		void UninstallEventFilter(ThreadSafeBase* filter);

	public:
		Signal<> Destoried;//析构信号

	protected:
		virtual void HandleEvent(Event* event);

		virtual void DeleteEvent(DeleteEvent* event);

		virtual void InvokeFunctionEvent(InvokeFunctionEvent* event);

		virtual bool FilterEvent(ThreadSafeBase* obj, Event* event);
	private:
		bool FilterEvent(Event* event);

	private:
		std::shared_ptr<ThreadSafeBase*> selfPointer;
		ConnectionRegistry m_Registry;
        template  <typename T>
        friend class ObjectPointer;


        friend class ::EventLoop;
	};

	template  <typename T>
	class ObjectPointer {
	public:
		ObjectPointer(T* target = NULL) {
			targetPointer = target->selfPointer;
		}
		ObjectPointer(const ObjectPointer<T>& other) {
			targetPointer = other.targetPointer;
		}

		T* operator->()
		{
			auto s = targetPointer.lock();
			if (s) {
				return dynamic_cast<T*>(*s);
			}
			return NULL;
		}

		T* operator->() const
		{
			auto s = targetPointer.lock();
			if (s) {
				return dynamic_cast<T*>(*s);
			}
			return NULL;
		}

		T* get() {
			auto s = targetPointer.lock();
			if (s) {
				return dynamic_cast<T*>(*s);
			}
			return (NULL);
		}

		T* get() const{
			auto s = targetPointer.lock();
			if (s) {
				return dynamic_cast<T*>(*s);
			}
			return (NULL);
		}

		operator T*() {
			auto s = targetPointer.lock();
			if (s) {
				return dynamic_cast<T*>(*s);
			}
			return (NULL);
		}

		std::weak_ptr<ThreadSafeBase*> targetPointer;
	};


	//用于存储ThreadSafe的容器，当注册进去的对象被释放后会自动从容器中注销
	class REFLECTX_EXPORT ObjectRegistryBase
	{
	private:
		ObjectRegistryBase(const ObjectRegistryBase& o);
		ObjectRegistryBase& operator = (const ObjectRegistryBase& o);
		bool operator == (const ObjectRegistryBase&o);

	public:
		ObjectRegistryBase();
		~ObjectRegistryBase();

		void Register(ThreadSafeBase* o);
		void UnRegister(ThreadSafeBase* o);

		std::unordered_set<ThreadSafeBase*> GetContent() const;

	protected:
		std::unordered_map<ThreadSafeBase*, ConnectionManager::ConnectionId> objs;
		mutable std::mutex mutex;
	};

	template<typename T>
	class ObjectRegistry:public ObjectRegistryBase
	{
	public:
		void Register(T* o) {
			ObjectRegistryBase::Register(o);
		}
		void UnRegister(ThreadSafeBase* o) {
			ObjectRegistryBase::UnRegister(o);
		}

		std::unordered_set<T*> GetContent() const {
			std::lock_guard<std::mutex> lock(mutex);
			std::unordered_set<T*> ret;
			for (auto&i : objs) {
				ret.insert(dynamic_cast<T*>(i.first));
			}

			return ret;
		}
	};
};




#endif // !THERAD_SAFE_H
